﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Transactions;
using ExcellentCRM.DataService.Exts;
using ExcellentCRM.DataService.Models;

namespace ExcellentCRM.DataService.Implements
{
    public class AccountService : BaseService<Account>
    {
        public Account GetModel(string userName, string password)
        {
            using (var dbCtx = new DataServiceContext())
            {
                var acct =
                    dbCtx.Accounts.Include("Staff").Include("Staff.Department")
                         .Include("StuClients")
                         .FirstOrDefault(
                             p =>
                             p.AcctName == userName && p.AcctPass == password && p.StatusToken != 0);
                return acct;
            }
        }

        public IList<Account> Search(Account acct, int pageSize, int pageIndex,
                                            out int totalCount)
        {
            using (var dbCtx = new DataServiceContext())
            {
                IQueryable<Account> searchQuery =
                    dbCtx.Accounts.Include("Staff").Include("Staff.Department")
                         .Include("StuClients")
                         .Where(p => p.StatusToken != 0);
                if (!string.IsNullOrWhiteSpace(acct.AcctName))
                {
                    string acctName = acct.AcctName;
                    searchQuery = dbCtx.Accounts.Where(p => p.AcctName.Contains(acctName));
                }
                if (acct.AcctType != AccountType.None)
                    searchQuery = searchQuery.Where(p => p.AcctType == acct.AcctType);
                totalCount = searchQuery.Count();
                return
                    searchQuery.OrderByDescending(p => p.Id)
                               .Skip(pageSize*(pageIndex - 1))
                               .Take(pageSize)
                               .ToList();
            }
        }

        public override ServiceResult Save(Account model)
        {
            return Save(model);
        }

        public ServiceResult Save(Account acct, Staff staff = null, StuClient stuClient = null)
        {
            using (var dbCtx = new DataServiceContext())
            {
                if (acct == null || acct.AcctType == AccountType.None)
                    return new ServiceResult(false, "acct为null或AcctType为None");
                using (var transScope = new TransactionScope())
                {
                    long acctId = acct.Id;
                    bool isNew = false;
                    if (acctId > 0)
                    {
                        var acctInDb = dbCtx.Accounts.FirstOrDefault(p => p.Id == acctId);
                        if (acctInDb == null)
                            throw new Exception(string.Format("Accounts表中不存在id为: {0} 的记录", acct.Id));
                        acctInDb.AcctPass = acct.AcctPass;
                        acctInDb.StatusToken = 1;
                        dbCtx.Entry(acctInDb).State = EntityState.Modified;
                    }
                    else
                    {
                        dbCtx.Accounts.Add(acct);
                        isNew = true;
                    }
                    dbCtx.SaveChanges();
                    //如果Account是新增，重新赋值acctId
                    acctId = acct.Id;
                    Role roleInDb = null;
                    if (acct.AcctType == AccountType.Staff)
                    {
                        if (staff == null)
                            throw new Exception(string.Format("新增普通用户帐号时，staff参数不能为空"));
                        if (isNew)
                        {
                            staff.AcctId = acctId;
                            dbCtx.Staff.Add(staff);
                            string deptName =
                                dbCtx.Departments.FirstOrDefault(p => p.Id == staff.DeptId).DeptName;
                            roleInDb =
                                dbCtx.Roles.FirstOrDefault(p => p.RoleName == deptName);
                            if(roleInDb == null)
                                throw new Exception(string.Format("Roles表中不存在Role Name为: {0} 的记录", deptName));
                            dbCtx.AccountRoles.Add(new AccountRole
                                {
                                    AcctId = acctId,
                                    RoleId = roleInDb.Id
                                });
                        }
                        else
                        {
                            var staffInDb = dbCtx.Staff.FirstOrDefault(p => p.AcctId == acctId);
                            if (staffInDb == null)
                                throw new Exception(string.Format("Staff表中不存在Account Id为: {0} 的记录", acctId));
                            staffInDb.DeptId = staff.DeptId;
                            staffInDb.StaffName = staff.StaffName;
                            staffInDb.Email = staff.Email;
                            staffInDb.Phone = staff.Phone;
                            staffInDb.StatusToken = 1;
                            dbCtx.Entry(staffInDb).State = EntityState.Modified;
                        }
                    }
                    else if (acct.AcctType == AccountType.Student)
                    {
                        if(stuClient == null)
                            throw new Exception(string.Format("新增学员用户帐号时，staff参数不能为空"));
                        if (isNew)
                        {
                            stuClient.AcctId = acctId;
                            dbCtx.StuClients.Add(stuClient);
                        }
                        else
                        {
                            var stuClientInDb =
                                dbCtx.StuClients.FirstOrDefault(p => p.AcctId == acctId);
                            if (stuClientInDb == null)
                                throw new Exception(string.Format("StuClients表中不存在Account Id为: {0} 的记录", acctId));
                            stuClientInDb.StudentInfo.StuName = stuClient.StudentInfo.StuName;
                            stuClientInDb.StudentInfo.Phone = stuClient.StudentInfo.StuName;
                            stuClientInDb.StudentInfo.CellPhone = stuClient.StudentInfo.StuName;
                            stuClientInDb.StudentInfo.Email = stuClient.StudentInfo.StuName;
                            stuClientInDb.StatusToken = 1;
                            dbCtx.Entry(stuClientInDb).State = EntityState.Modified;
                        }
                    }
                    if (acct.AcctType == AccountType.Student ||
                        acct.AcctType == AccountType.Admin)
                    {
                        string acctTypeStr = acct.AcctType.ToString();
                        roleInDb =
                            dbCtx.Roles.FirstOrDefault(p => p.RoleName == acctTypeStr);
                        if (roleInDb == null)
                            throw new Exception(string.Format("Roles表中不存在Role Name为: {0} 的记录", acctTypeStr));
                        dbCtx.AccountRoles.Add(new AccountRole
                        {
                            AcctId = acctId,
                            RoleId = roleInDb.Id
                        });
                    }
                    dbCtx.SaveChanges();
                    transScope.Complete();
                }
                return ServiceResult.SuccessResult;
            }
        }

        public bool AcctIsExists(string acctName, AccountType? acctType, long? acctId)
        {
            using (var dbCtx = new DataServiceContext())
            {
                long idVal = acctId ?? -1;

                var searchQuery = dbCtx.Accounts.Where(p => p.AcctName == acctName && p.Id != idVal);

                if (acctType.HasValue && acctType.Value != AccountType.None)
                    searchQuery = searchQuery.Where(p => p.AcctType == acctType.Value);
                return searchQuery.Any();
            }
        }

        public Account GetModel(long id, bool includeChild = true)
        {
            using (var dbCtx = new DataServiceContext())
            {
                DbQuery<Account> acctsQuery = dbCtx.Accounts;
                if (includeChild)
                    acctsQuery = acctsQuery.Include("Staff").Include("Staff.Department")
                                           .Include("StuClients");
                return acctsQuery.FirstOrDefault(p => p.Id == id);
            }
        }

        public override ServiceResult Delete(long id)
        {
            using (var dbCtx = new DataServiceContext())
            {
                using (var tranScope = new TransactionScope())
                {
                    var acct = dbCtx.Accounts.FirstOrDefault(p => p.Id == id);
                    if (acct == null)
                        return new ServiceResult(false, "数据库中未发现该记录");
                    acct.StatusToken = 0;
                    acct.LastModifiedTime = DateTime.Now;
                    switch (acct.AcctType)
                    {
                        case AccountType.Staff:
                            {
                                var staff = dbCtx.Staff.FirstOrDefault(p => p.AcctId == id);
                                if (staff != null)
                                {
                                    staff.StatusToken = 0;
                                    staff.LastModifiedTime = DateTime.Now;
                                    dbCtx.Entry(staff).State = EntityState.Modified;
                                }
                            }
                            break;
                        case AccountType.Student:
                            {
                                var stuClient = dbCtx.StuClients.FirstOrDefault(p => p.AcctId == id);
                                if (stuClient != null)
                                {
                                    stuClient.StatusToken = 0;
                                    stuClient.LastModifiedTime = DateTime.Now;
                                    dbCtx.Entry(stuClient).State = EntityState.Modified;
                                }
                            }
                            break;
                    }
                    dbCtx.SaveChanges();
                    tranScope.Complete();
                }
                return ServiceResult.SuccessResult;
            }
        }
    }
}